package com.th.therp.service.Impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.th.therp.exception.BaseException;
import com.th.therp.mapper.MaterialMapper;
import com.th.therp.pojo.dto.page.MaterialPageQueryDTO;
import com.th.therp.pojo.emtity.Material;
import com.th.therp.pojo.result.PageResult;
import com.th.therp.pojo.vo.MaterialVo;
import com.th.therp.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.beans.Transient;
import java.util.ArrayList;
import java.util.List;

@Service
public class MaterialServiceImpl implements MaterialService {

    @Autowired
    private MaterialMapper materialMapper;

    @Autowired
    @Lazy
    private VendorService vendorService;

    @Autowired
    @Lazy
    private InventoryService inventoryService;

    @Autowired
    @Lazy
    private MaterialCategoryService materialCategoryService;

    @Autowired
    @Lazy
    private MaterialBrandService materialBrandService;


    @Override
    public void add(Material material) {
        String barcode = material.getBarcode();
        String name = material.getName();
        Integer vendor = material.getVendor();

        String vendorName = vendorService.findNameById(vendor);
        Integer barcodeCount = materialMapper.findCountByBarcodeAndVendor(barcode,vendor);
        Integer nameCount = materialMapper.findCountByNameAndVendor(name,vendor);

        if (barcodeCount != 0 ) {
            throw new BaseException(vendorName+"：该供应商下已有相同条码商品");
        }
        if (nameCount != 0 ){
            throw new BaseException(vendorName+"：该供应商下已有相同名称商品");
        }
        materialMapper.add(material);
    }

    @Override
    public PageResult page(MaterialPageQueryDTO materialPageQueryDTO) {
        PageHelper.startPage(materialPageQueryDTO.getPageNum(), materialPageQueryDTO.getPageSize());
        Page<Material> page = materialMapper.page(materialPageQueryDTO);
        List<MaterialVo> materialVoList = new ArrayList<>();
        for (Material material : page.getResult()) {
            String vendorName = vendorService.findNameById(material.getVendor());
            String categoryName = materialCategoryService.findCategoryNameById(material.getCategory());
            String brandName = materialBrandService.findBrandNameById(material.getBrand());
            materialVoList.add(MaterialVo.builder()
                    .id(material.getId())
                    .barcode(material.getBarcode())
                    .vendor(vendorName)
                    .name(material.getName())
                    .specification(material.getSpecification())
                    .unit(material.getUnit())
                    .category(categoryName)
                    .brand(brandName)
                    .purchasePrice(material.getPurchasePrice())
                    .sellingPrice(material.getSellingPrice())
                    .status(material.getStatus())
                    .build());
        }
        return new PageResult(page.getTotal(), materialVoList);
    }

    @Override
    public void update(Material material) {
        // 获取新的值
        String newBarcode = material.getBarcode();
        String newName = material.getName();
        Integer vendor = material.getVendor();

        // 获取数据库中当前数据
        Material existingMaterial = materialMapper.findById(material.getId());
        // 如果条码和名称都没变，直接更新
        if (existingMaterial.getBarcode().equals(newBarcode)
                && existingMaterial.getName().equals(newName)) {
            materialMapper.update(material);
        }

        // 核对条码和名称的唯一性
        Integer barcodeCount = materialMapper.findCountByBarcodeAndVendor(newBarcode, vendor);
        if (!existingMaterial.getBarcode().equals(newBarcode) && barcodeCount > 0) {
            throw new BaseException("该供应商下已有相同条码商品：" + newBarcode);
        }
        Integer nameCount = materialMapper.findCountByNameAndVendor(newName, vendor);
        if (!existingMaterial.getName().equals(newName) && nameCount > 0) {
            throw new BaseException("该供应商下已有相同名称商品：" + newName);
        }

        materialMapper.update(material);
    }


    @Override
    public void delete(List<Integer> ids) {
        ids.forEach(id ->{
             String barcode = materialMapper.findMaterialBarcodeById(id);
             String materialName = materialMapper.findMaterialNameById(id);
             Integer Quantity = inventoryService.findQuantityByBarcode(barcode);
             if (Quantity>0){
                 throw new BaseException(materialName+"：该商品有库存，不可删除");
             }else {
                 Material material = new Material();
                 material.setId(id);
                 material.setIsDeleted(1);
                 materialMapper.update(material);
             }
        });
    }

    @Override
    public List<Material> findByVendorId(Long vendorId) {
        return materialMapper.findByVendorId(vendorId);
    }

    @Override
    @Transient
    public Material findByBarcodeId(String materialBarcode) {
        Material material = materialMapper.findByBarcodeId(materialBarcode);
        if (material == null) {
            throw new BaseException("该仓库无商品");
        }
        return material;
    }

    @Override
    public Material findById(Integer materialId) {
        return materialMapper.findById(materialId);
    }

    @Override
    public double findPurchasePriceById(Integer materialId) {
        return materialMapper.findPurchasePriceById(materialId);
    }

    @Override
    public double findSellingPriceById(Integer materialId) {
        return materialMapper.findSellingPriceById(materialId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(List<Integer> idList, Integer status) {
        idList.forEach(id->{
            Material material = Material.builder()
                    .id(id)
                    .status(status)
                    .build();
            materialMapper.update(material);
        });
    }

    @Override
    public String findMaterialNameById(Integer materialId) {
        return materialMapper.findMaterialNameById(materialId);
    }

    @Override
    public Integer findMaterCategoryById(Integer materialId) {
        return materialMapper.findMaterialCategoryById(materialId);
    }

    @Override
    public Integer findMaterialBrandById(Integer materialId) {
        return materialMapper.findMaterialBrandById(materialId);
    }

    @Override
    public String findMaterialBarcodeById(Integer materialId) {
        return materialMapper.findMaterialBarcodeById(materialId);
    }
}